﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using BoxSharp;

namespace BoxSharpRunPath
{
    public class BoxSharpRunPath : AddonInstance
    {
        private AddonInterface myInterface;
        private ToolTip tip;
        private bool deletingText = false;
        private string lastFatherPath = "";
        private int lastChildIndex = -1;

        public override void AddonMain(AddonInterface addonInterface)
        {
            myInterface = addonInterface;

            myInterface.AddonInitializing += new AddonEventHandler(myInterface_AddonInitializing);
            myInterface.AddonFinalizing += new AddonEventHandler(myInterface_AddonFinalizing);
        }

        void myInterface_AddonFinalizing()
        {
        }

        void myInterface_AddonInitializing()
        {
            tip = new ToolTip();
            tip.HasDropShadow = true;
            tip.PlacementTarget = myInterface.Box;
            tip.Placement = System.Windows.Controls.Primitives.PlacementMode.Bottom;
            tip.IsOpen = false;
            tip.Padding = new Thickness(5);
            tip.VerticalOffset = 5;

            myInterface.Box.PreviewKeyDown += new System.Windows.Input.KeyEventHandler(Box_PreviewKeyDown);
            myInterface.Box.TextChanged += new TextChangedEventHandler(Box_TextChanged);
            myInterface.OnCommand += new CommandEventHandler(myInterface_OnCommand);
        }

        void myInterface_OnCommand(string bscommand)
        {
            if (bscommand.StartsWith("/"))
            {
                if (bscommand.ToLower().StartsWith("/run "))
                {
                    string command = bscommand.Substring(5);
                    string args = "";

                    int sepPos = command.IndexOf(' ');
                    if (sepPos > -1)
                    {
                        args = command.Substring(sepPos + 1);
                        command = command.Substring(0, sepPos);
                    }

                    try
                    {
                        System.Diagnostics.Process.Start(command,args);
                        myInterface.Box.Text = "";
                    }
                    catch (System.Exception ex)
                    {
                        MessageBox.Show("Error occurred while running the command. Here's the error message:\r\n\r\n" + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                    }
                }
                return;
            }

            if (bscommand.ToLower().StartsWith("http://"))
            {
                try
                {
                    System.Diagnostics.Process.Start(bscommand);
                }
                catch (System.Exception ex)
                {
                    MessageBox.Show("Error occurred while running the command. Here's the error message:\r\n\r\n" + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                }

                myInterface.Box.Text = "";
            }
            else if (System.IO.Path.IsPathRooted(bscommand))
            {
                try
                {
                    System.Diagnostics.Process.Start(bscommand);
                }
                catch (System.Exception ex)
                {
                    MessageBox.Show("Error occurred while running the command. Here's the error message:\r\n\r\n" + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                }

                myInterface.Box.Text = "";
            }
        }

        void Box_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
        {
            if (e.Key == System.Windows.Input.Key.Delete || e.Key == System.Windows.Input.Key.Back)
            {
                deletingText = true;
            }

            if (e.Key == System.Windows.Input.Key.Tab)
            {
                if (System.IO.Path.IsPathRooted(myInterface.Box.Text))
                {
                    int pathEnd = myInterface.Box.Text.LastIndexOfAny(new char[] { '/', '\\' });

                    if (pathEnd >= 0)
                    {
                        deletingText = true;
                        e.Handled = true;

                        string pathFront = myInterface.Box.Text.Substring(0, pathEnd + 1);

                        if (System.IO.Directory.Exists(pathFront))
                        {
                            if (pathFront == lastFatherPath)
                            {
                                lastChildIndex++;

                                System.IO.DirectoryInfo fatherDir = new System.IO.DirectoryInfo(lastFatherPath);
                                System.IO.DirectoryInfo[] childDirs = fatherDir.GetDirectories("*", System.IO.SearchOption.TopDirectoryOnly);

                                if (childDirs.Length > 0)
                                {
                                    if (lastChildIndex >= childDirs.Length)
                                    {
                                        lastChildIndex = 0;
                                    }

                                    myInterface.Box.Text = pathFront + childDirs[lastChildIndex].Name;
                                    myInterface.Box.CaretIndex = myInterface.Box.Text.Length;
                                }
                            }
                            else
                            {
                                lastChildIndex = 0;
                                lastFatherPath = pathFront;

                                System.IO.DirectoryInfo fatherDir = new System.IO.DirectoryInfo(lastFatherPath);
                                System.IO.DirectoryInfo[] childDirs = fatherDir.GetDirectories("*", System.IO.SearchOption.TopDirectoryOnly);

                                if (childDirs.Length > 0)
                                {
                                    myInterface.Box.Text = pathFront + childDirs[lastChildIndex].Name;
                                    myInterface.Box.CaretIndex = myInterface.Box.Text.Length;
                                }
                            }
                        }
                    }
                }
            }
        }

        void Box_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (myInterface.Box.Text.StartsWith("/"))
            {
                if (myInterface.Box.Text.ToLower() == "/run" || myInterface.Box.Text.ToLower().StartsWith("/run "))
                {
                    tip.Content = "/run command\r\nShell execute the command.";
                    tip.IsOpen = true;

                }
                else
                {
                    tip.IsOpen = false;
                }
                return;
            }

            if (myInterface.Box.Text.ToLower().StartsWith("http://"))
            {
                tip.Content = "Open the browser to explore the Internet.";
                tip.IsOpen = true;
            }
            else if (System.IO.Path.IsPathRooted(myInterface.Box.Text))
            {
                int pathEnd = myInterface.Box.Text.LastIndexOfAny(new char[] { '/', '\\' });

                if (pathEnd >= 0)
                {
                    tip.Content = "Open the folder.";
                    tip.IsOpen = true;

                    if (!deletingText)
                    {
                        string pathFront = myInterface.Box.Text.Substring(0, pathEnd + 1);
                        string pathTail = myInterface.Box.Text.Substring(pathEnd);
                        if (pathTail.Length == 1)
                        {
                            pathTail = "";
                        }
                        else
                        {
                            pathTail = pathTail.Substring(1);
                        }

                        if (System.IO.Directory.Exists(pathFront))
                        {
                            System.IO.DirectoryInfo currentDir = new System.IO.DirectoryInfo(pathFront);
                            System.IO.DirectoryInfo[] findResults = currentDir.GetDirectories("*", System.IO.SearchOption.TopDirectoryOnly);

                            if (findResults.Length > 0)
                            {
                                for (int i = 0; i < findResults.Length; ++i)
                                {
                                    if (findResults[i].Name.ToLower().StartsWith(pathTail.ToLower()) && findResults[i].Name.Length > pathTail.Length)
                                    {
                                        string append = findResults[i].Name.Substring(pathTail.Length);

                                        int originLength = myInterface.Box.Text.Length;
                                        myInterface.Box.Text += append;
                                        myInterface.Box.Select(originLength, append.Length);

                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                tip.IsOpen = false;
            }

            deletingText = false;
        }
    }
}
